(function ($) {


    function AutoSelectinit(srcelement) {
        var srctargetele = $(srcelement);

        this.mydefault = {


            srcTarget: srctargetele,
            header: true,
            autoOpen: true,
            controlWidth: "227px",
            headerHeight: "27px",
            minWidth: 225,
            classes: '',
            checkAllText: '全选',
            checkAllIDClass: "mycka",
            uncheckAllText: '全不选',
            uncheckAllIDClass: "myckna",
            listBoxHeight: "175px",
            closeAllIDClass: "myckca",
            noneSelectedText: '==请选择==',
            selectedText: '# 项已选择',
            selectedList: 0,
            show: null,
            hide: null,
            autoOpen: false,
            multiple: true,
            position: {},
            appendTo: "body",
            button: null,
            buttonlabel: null,
            buttoninput: null,
            isOpen: true,
            changeSelectText: true,
            onChangeValueFunction: null,
            onChangeTextFunction: null,
            isInputSearchBinded: false,
            url: null,
            dataType: 'json',
            parse: null,
            isLoading: false,
            extraParams: {},
            data: {},
            length: 0,
            cacheLength: 200,
            allData: [],
            allSelectedData: [],
            asyncLoad: null,
            autoCheck: false
        };

        return this;

    }

    $.fn.AutoSelect = function (option) {

        if (typeof (option) == "string") {
            var AutoSelectinst = this.data("AutoSelect");

            if (AutoSelectinst) {
                if ($.isFunction(AutoSelectinst[option])) {
                    return AutoSelectinst[option].apply(AutoSelectinst, Array.prototype.slice.call(arguments, 1));
                }

            }
        }
        else {

            // var $this = this;


            var data = this.data("AutoSelect");
            if (!data) {
                this.data("AutoSelect", new AutoSelectinit(this));
            }
            this.data("AutoSelect").setdefault(option);

            this.data("AutoSelect").attachPlugin();


            return this;
        }

    };
    $.extend(AutoSelectinit.prototype, {
        attachPlugin: function () {
            var that = this;
            this.startCreatElement();
            this.removeSrcElement();
            this.initbuttonPostion();
            if (!this.mydefault.autoOpen) {

                this.mydefault.mymenu.hide();
                this.mydefault.isOpen = false;
            }
            this.bindHeaderCheck();
            this.bindCloseLink();
            this.bingContentCheck();

            var tmo;
            if (!this.mydefault.isInputSearchBinded) {

                this.mydefault.buttoninput.bind("input propertychange", function (event) {
                    clearTimeout(tmo);
                    tmo = setTimeout(function () {
                        that.bindInputSearch()
                    }, 200);

                });

                this.mydefault.isInputSearchBinded = true;
            }

        },
        startCreatElement: function () {
            var buttonEle = (this.mydefault.button = $('<button type="button"  style="width:' + this.mydefault.controlWidth + ';color: #eb8f00;font-weight: bold;border:1px solid #fbd850;background-color: #FFFFFF;height: ' + this.mydefault.headerHeight + ';text-align: center;font-size: 1.1em"></button>'));
            buttonEle.insertAfter(this.mydefault.srcTarget);

            var buttonlabel = (this.mydefault.buttonlabel = $('<span />'))
                .html(this.mydefault.noneSelectedText)
                .appendTo(buttonEle);

            var buttoninput = (this.mydefault.buttoninput = $('<input type="text" value="" id="mybuttoninput"  name="mybuttoninput" style="width: ' + this.mydefault.controlWidth + ';height: ' + this.mydefault.headerHeight + ';text-align: left;border: 1px solid #fbd850;line-height:' + this.mydefault.headerHeight + '"/>'))
                .hide().insertAfter(this.mydefault.srcTarget);

            var menu = (this.mydefault.mymenu = $(' <div style="padding: 3px;border: 1px solid #dddddd;background-color: #eeeeee;width:' + this.mydefault.controlWidth + ';"></div>'))

                .appendTo($(this.mydefault.appendTo));
            var headerLinkContainer = (this.mydefault.headerLinkContainer = $('<ul style="position: relative;width:' + (parseInt(this.mydefault.controlWidth.replace('px', '')) - 10) + 'px;color: #2779aa;font-weight: bold;border: 1px solid #e78f08;background-color:#f6a828;height: 21px;text-align: center;font-size: 1.1em;list-style: none;padding: 0px;margin:0px"> <li style="float: left;font-size: 11px;color: white;position: absolute;top: 0px;height: 21px;width:' + (parseInt(this.mydefault.controlWidth.replace('px', '') - 10) / 3) + 'px;left: 0px;"> <lable style=""> <a href="#"  class="' + this.mydefault.checkAllIDClass + '" onselectstart="return false;" style="color: white;font-size: 12px;text-decoration: none;line-height:21px;">' + this.mydefault.checkAllText + '</a> </lable> </li> <li style="float: left;font-size: 11px;color:white;position: absolute;top: 0px;height: 21px;width:' + (parseInt(this.mydefault.controlWidth.replace('px', '') - 10) / 3) + 'px ;left: ' + (parseInt(this.mydefault.controlWidth.replace('px', '') - 10) / 3) + 'px;"> <lable style="">  <a href="#" onselectstart="return false;" class="' + this.mydefault.uncheckAllIDClass + '"  style="color: white;font-size: 12px;text-decoration: none;line-height:21px;">' + this.mydefault.uncheckAllText + '</a> </li> <li style="float: left;font-size: 11px;color:white;position: absolute;top: 0px;height: 21px;width:' + ((parseInt(this.mydefault.controlWidth.replace('px', '') - 10) / 3)) + 'px ;left: ' + ((parseInt(this.mydefault.controlWidth.replace('px', '') - 10) * 2) / 3) + 'px;"> <lable style="">  <a href="#" onselectstart="return false;" class="' + this.mydefault.closeAllIDClass + '"  style="color: white;font-size: 12px;text-decoration: none;line-height:21px;">关闭</a> </li> </ul>'))
                .appendTo(menu);
            var checkboxContainer = (this.mydefault.checkboxContainer = $('  <ul  style="height: ' + this.mydefault.listBoxHeight + ';overflow-y: auto;position:relative;margin: 0px;padding: 0px;list-style:none;" class="ui-multiselect-checkboxes ui-widget">'))
                .appendTo(menu);
            this.dorefresh();
            this.doSetButtonWidth();


            setTimeout($.proxy(function () {

                this.updateSelectState();
            }, this), 10)

        },
        removeSrcElement: function () {

            this.mydefault.srcTarget.remove();
        },
        dorefresh: function () {


            var el = this.mydefault.srcTarget;
            var that = this;
            el.find('option').each(function (i) {
                var myid = "option" + i;
                var result = $(this).text();
                var value = $(this).val();
                var seled = $(this).is(":selected") ? true : false;
                var checkboxli = $(' <li class=" "><label for="ui-multiselect-sela-option-3" title="" class="ui-corner-all"><input id="' + myid + '" name="' + myid + '" type="checkbox" value="' + value + '" ' + (seled ? 'checked="checked"' : '') + '><span>' + result + '</span></label></li>')
                    .hover(function () {

                        $(this).addClass("ui-state-hover");
                    }, function () {


                        $(this).removeClass("ui-state-hover");
                    });


                that.mydefault.checkboxContainer.append(checkboxli);
            });


        },
        updateSelectState: function () {
            var that = this;
            var allCheckElements = this.mydefault.checkboxContainer.find('input[type="checkbox"]');
            var allCheckedElements = this.mydefault.checkboxContainer.find('input[type="checkbox"]').filter(":checked");
            var allCheckedElementsTexts = allCheckedElements.siblings('span');
            var allLen = allCheckElements.length;
            var checkedLen = allCheckedElements.length;
            var checkedValues = $.map(allCheckedElements, function (n) {

                return $(n).val();
            });

            var checkedTexts = $.map(allCheckedElementsTexts, function (n) {

                return $(n).text();
            });
            this.mydefault.allSelectedData = [];
            allCheckedElements.each(function () {

                var n = this;
                var result = $(n).siblings('span').text();
                var value = $(n).val();
                var seled = true;
                that.mydefault.allSelectedData.push({ result: result, value: value, seled: seled });

            })
            if (this.mydefault.changeSelectText) {

                if (checkedLen > 0) {
                    var tempValue = this.mydefault.selectedText.replace("#", checkedLen);
                    this.mydefault.buttonlabel.html(tempValue);
                } else {

                    this.mydefault.buttonlabel.html(this.mydefault.noneSelectedText);
                }
            }

            if ($.isFunction(this.mydefault.onChangeValueFunction)) {
                this.mydefault.onChangeValueFunction(checkedValues);
            }
            if ($.isFunction(this.mydefault.onChangeTextFunction)) {

                this.mydefault.onChangeTextFunction(checkedTexts);
            }
        }
        ,
        bindHeaderCheck: function () {

            var that = this;
            this.mydefault.button.bind("click", $.proxy(function () {

                this.doRequestElement();
                this.toggleOpenClose();
                this.initInputPosition();
            }, this));
            this.mydefault.headerLinkContainer.delegate("a." + this.mydefault.checkAllIDClass, "click", function (e) {
                e.preventDefault();
                that.mydefault.mymenu.find('input[type="checkbox"]').each(function () {

                    $(this).attr("checked", "checked");
                });
                setTimeout($.proxy(function () {

                    this.updateSelectState();
                }, that), 10)
            });
            this.mydefault.headerLinkContainer.delegate("a." + this.mydefault.uncheckAllIDClass, "click", function (e) {
                that.mydefault.mymenu.find('input[type="checkbox"]').each(function () {

                    $(this).attr("checked", false);
                });
                setTimeout($.proxy(function () {

                    this.updateSelectState();
                }, that), 10)
            });
            this.mydefault.headerLinkContainer.find("a." + this.mydefault.checkAllIDClass).hover(function (e) {
                $(this).css({ "text-decoration": "underline" });

            }, function (q) {

                $(this).css({ "text-decoration": "none" });
            });
            this.mydefault.headerLinkContainer.find("a." + this.mydefault.uncheckAllIDClass).hover(function (e) {
                $(this).css({ "text-decoration": "underline" });

            }, function (q) {

                $(this).css({ "text-decoration": "none" });
            });


        },

        bindCloseLink: function () {


            this.mydefault.headerLinkContainer.find("." + this.mydefault.closeAllIDClass).bind("click", $.proxy(function () {
                this.toggleOpenClose();
                this.mydefault.button.show();
                this.mydefault.buttoninput.hide();
            }, this));
        },
        doRequestElement: function () {

            this.mydefault.button.hide();
            this.mydefault.buttoninput.show();


        },
        flush: function () {
            this.mydefault.data = {};
            this.mydefault.length = 0;
        },
        cacheLoad: function (q) {

            if (this.mydefault.length == 0) {

                return null;
            }
            if (this.mydefault.data[q]) {
                return this.mydefault.data[q];
            } else {

                return null;
            }


        },
        cacheAdd: function (q, value) {
            if (this.mydefault.length > this.mydefault.cacheLength) {
                this.flush();
            }
            if (!this.mydefault.data[q]) {
                this.mydefault.length++;
            }
            this.mydefault.data[q] = value;
        },

        flush: function () {

            this.mydefault.data = {};
            this.mydefault.length = 0;
        },
        stopLoading: function (tm) {

            clearTimeout(tm);
        },
        receiveData: function (q, data) {
            var that = this;
            if (data && data.length) {


                if (this.mydefault.asyncLoad != null) {
                    this.stopLoading(this.mydefault.asyncLoad);
                }
                this.mydefault.asyncLoad = setTimeout($.proxy(function () {
                    this.fillList(q, data);
                }, this), 1000);
                // this.rebingContentCheck();

            } else {

                // this.hideNoResult();

                if (!this.mydefault.autoCheck) {

                    setTimeout(function () {
                        that.checkSearch();
                    }, 1000);
                }
            }
        },
        checkreceiveData: function (q, data) {


            if (!data | data.length == 0) {


                this.hideNoResult();

            }

        },
        checkSearch: function () {

            var that = this;
            var t = this.mydefault.buttoninput.val();


            that.requestSearch(t, $.proxy(that.checkreceiveData, this), $.proxy(that.hideNoResult, this));

            this.mydefault.autoCheck = true;


        },
        checkDataHasSelected: function (k) {
            var isHas = false;
            for (var j = 0; j < this.mydefault.allSelectedData.length; j++) {

                if (this.mydefault.allSelectedData[j].result == k.result & this.mydefault.allSelectedData[j].value == k.value & this.mydefault.allSelectedData[j].seled) {

                    isHas = true;
                }
            }
            return isHas;
        },
        fillList: function (q, valdata) {
            this.mydefault.checkboxContainer.empty();
            var intersection = [];
            var that = this;
            var ci = 1;
            for (var i = 0; i < valdata.length; i++) {

                var myid = "option" + ci;
                var result = valdata[i].result;
                var value = valdata[i].value;


                var seled = false;

                if (!this.checkDataHasSelected(valdata[i])) {
                    var checkboxli = $(' <li class=" "><label for="ui-multiselect-sela-option-3" title="" class="ui-corner-all"><input id="' + myid + '" name="' + myid + '" type="checkbox" value="' + value + '" ' + (seled ? 'checked="checked"' : '') + '><span>' + result + '</span></label></li>')
                        .hover(function () {

                            $(this).addClass("ui-state-hover");
                        }, function () {


                            $(this).removeClass("ui-state-hover");
                        });
                    ci++;
                    this.mydefault.checkboxContainer.append(checkboxli);
                } else {
                    valdata[i].seled = true;
                    intersection.push(valdata[i]);
                }
            }
            if (intersection.length > 0) {
                for (var r = 0; r < intersection.length; r++) {
                    var myid = "option" + ci;
                    var result = intersection[r].result;
                    var value = intersection[r].value;


                    var seled = true;


                    var checkboxli = $(' <li class=" "><label for="ui-multiselect-sela-option-3" title="" class="ui-corner-all"><input id="' + myid + '" name="' + myid + '" type="checkbox" value="' + value + '" ' + (seled ? 'checked="checked"' : '') + '><span>' + result + '</span></label></li>')
                        .hover(function () {

                            $(this).addClass("ui-state-hover");
                        }, function () {


                            $(this).removeClass("ui-state-hover");
                        });
                    ci++;
                    this.mydefault.checkboxContainer.append(checkboxli);
                }

            }
            var oldSelected = $.grep(this.mydefault.allSelectedData, function (k, i) {

                var isHas = false;
                for (var j = 0; j < intersection.length; j++) {

                    if (intersection[j].result == k.result & intersection[j].value == k.value) {

                        isHas = true
                    }
                }
                return isHas;
            }, true);

            if (oldSelected.length > 0) {
                for (var h = 0; h < oldSelected.length; h++) {

                    var myid = "option" + ci;
                    var result = oldSelected[h].result;
                    var value = oldSelected[h].value;


                    var seled = true;


                    var checkboxli = $(' <li class=" "><label for="ui-multiselect-sela-option-3" title="" class="ui-corner-all"><input id="' + myid + '" name="' + myid + '" type="checkbox" value="' + value + '" ' + (seled ? 'checked="checked"' : '') + '><span>' + result + '</span></label></li>')
                        .hover(function () {

                            $(this).addClass("ui-state-hover");
                        }, function () {


                            $(this).removeClass("ui-state-hover");
                        });
                    ci++;
                    this.mydefault.checkboxContainer.append(checkboxli);

                }
            }
            this.mydefault.checkboxContainer.find('input[type="checkbox"]').change(function () {

                if ($(this).is(":checked")) {
                    $(this).removeAttr("checked");
                } else {

                    $(this).attr("checked", true);
                }
                setTimeout($.proxy(function () {

                    this.updateSelectState();
                }, that), 10)

            });
            this.mydefault.checkboxContainer.scrollTop(0);
        },
        hideNoResult: function () {

            this.mydefault.checkboxContainer.empty();
            if (this.mydefault.allSelectedData.length) {
                var ci = 1;
                for (var h = 0; h < this.mydefault.allSelectedData.length; h++) {

                    var myid = "option" + ci;
                    var result = this.mydefault.allSelectedData[h].result;
                    var value = this.mydefault.allSelectedData[h].value;


                    var seled = true;


                    var checkboxli = $(' <li class=" "><label for="ui-multiselect-sela-option-3" title="" class="ui-corner-all"><input id="' + myid + '" name="' + myid + '" type="checkbox" value="' + value + '" ' + (seled ? 'checked="checked"' : '') + '><span>' + result + '</span></label></li>')
                        .hover(function () {

                            $(this).addClass("ui-state-hover");
                        }, function () {


                            $(this).removeClass("ui-state-hover");
                        });
                    ci++;
                    this.mydefault.checkboxContainer.append(checkboxli);

                }
                this.mydefault.checkboxContainer.scrollTop(0);
            }
        },
        bindInputSearch: function () {
            this.mydefault.autoCheck = false;
            var t = this.mydefault.buttoninput.val();


            this.requestSearch(t, $.proxy(this.receiveData, this), $.proxy(this.hideNoResult, this))
        },
        requestSearch: function (term, success, failure) {
            var that = this;
            var data = this.cacheLoad(term);
            // recieve the cached dataf
            if (data && data.length) {

                success(term, data);

            } else {
                $.ajax({


                    url: this.mydefault.url,

                    dataType: 'json',
                    data: $.extend({}, {
                        q: term

                    }, this.mydefault.extraParams),
                    error: function (e) {


                    },
                    success: function (data) {

                        var parsed = that.mydefault.parse(data);

                        that.cacheAdd(term, parsed);
                        success(term, parsed);

                    }
                });
            }
        },
        bingContentCheck: function () {

            var that = this;
            this.mydefault.checkboxContainer.delegate("li", "click", function () {

                $(this).find('input[type="checkbox"]').each(function () {
                    if ($(this).is(":checked")) {
                        $(this).removeAttr("checked");
                    } else {

                        $(this).attr("checked", true);
                    }
                });

                setTimeout($.proxy(function () {

                    this.updateSelectState();
                }, that), 10)
            });
            this.mydefault.checkboxContainer.find('input[type="checkbox"]').change(function () {

                if ($(this).is(":checked")) {
                    $(this).removeAttr("checked");
                } else {

                    $(this).attr("checked", true);
                }
                setTimeout($.proxy(function () {

                    this.updateSelectState();
                }, that), 10)

            });
        }
        ,

        doSetButtonWidth: function () {
            var mywd = $(this.mydefault.button).outerWidth();
            $(this.mydefault.mymenu).outerWidth(mywd);
        }
        ,
        toggleOpenClose: function () {
            if (this.mydefault.isOpen) {

                this.mydefault.mymenu.fadeOut();

                this.mydefault.isOpen = false;
            } else {

                this.mydefault.mymenu.fadeIn();

                this.mydefault.isOpen = true;
            }


        }
        ,
        initInputPosition: function () {

            var pos = this.mydefault.buttoninput.offset();

            this.mydefault.mymenu.css({
                top: pos.top + this.mydefault.buttoninput.outerHeight(),
                left: pos.left,
                position: "absolute"
            });

        },
        initbuttonPostion: function () {

            var pos = this.mydefault.button.offset();

            this.mydefault.mymenu.css({
                top: pos.top + this.mydefault.button.outerHeight(),
                left: pos.left,
                position: "absolute"
            });

        }
        ,
        setdefault: function (opt) {

            $.extend(true, this.mydefault, opt);


        }
    })
    ;

    $.fn.AutoSelect.constructor = AutoSelectinit;

})
(jQuery);